home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Telnet 2.6.1d1 4⁄26⁄94 Folder / source / config / configure.c next >
Text File  |  1994-04-18  |  37KB  |  1,146 lines

  1. /*    Configure.c
  2. *    New Configuration scheme (the death of config.tel)
  3. *
  4. *****************************************************************
  5. *    NCSA Telnet for the Macintosh                                *
  6. *                                                                *
  7. *    National Center for Supercomputing Applications                *
  8. *    Software Development Group                                    *
  9. *    152 Computing Applications Building                            *
  10. *    605 E. Springfield Ave.                                        *
  11. *    Champaign, IL  61820                                        *
  12. *                                                                *
  13. *    Copyright (c) 1986-1993,                                    *
  14. *    Board of Trustees of the University of Illinois                *
  15. *****************************************************************
  16. *  Revisions:
  17. *  8/92        Telnet 2.6:    Initial version.  Jim Browne
  18. */
  19.  
  20. #ifdef MPW
  21. #pragma segment Configure
  22. #endif
  23.  
  24. #include "TelnetHeader.h"
  25.  
  26. #include <stdio.h>
  27. #include <ctype.h>
  28. #include <Picker.h>
  29.  
  30. #include "newresrc.h"
  31.  
  32. #include "DlogUtils.proto.h"
  33. #include "popup.h"
  34. #include "popup.proto.h"
  35. #include "configure.proto.h"
  36. #include "netevent.proto.h"        /* For Stask proto */
  37. #include "prefs.proto.h"
  38. #include "bkgr.proto.h"            // For StartUpFTP proto
  39. #include "menuseg.proto.h"
  40. #include "macutil.proto.h"        
  41.  
  42. static    pascal short TerminalModalProc( DialogPtr dptr, EventRecord *evt, short *item);
  43. PROTO_UPP(TerminalModalProc, ModalFilter);
  44. static    pascal short SessionModalProc(DialogPtr dptr, EventRecord *evt, short *item);
  45. PROTO_UPP(SessionModalProc, ModalFilter);
  46. static    pascal short MyDlogWListFilter( DialogPtr dptr, EventRecord *evt, short *item);
  47. PROTO_UPP(MyDlogWListFilter, ModalFilter);
  48.  
  49. static    pascal listDitemproc(DialogPtr theDlg, short itemNo);
  50. PROTO_UPP(listDitemproc, UserItem);
  51.  
  52. extern SysEnvRec theWorld;        /* BYU 2.4.18 - System Environment record */
  53. extern    FTPServerPrefs*        gFTPServerPrefs;
  54. extern    ApplicationPrefs*    gApplicationPrefs;
  55.  
  56. static    void ZeroNumOnly(void);
  57. static    Boolean InNumOnly(short item);
  58.  
  59. #define NUMONLYSIZE 8
  60. short NumOnly[NUMONLYSIZE];        /* Items for which non-number keys are ignored */
  61.                                 // NumOnly[0] is number of "safe" item to return
  62.  
  63. void    CONFIGUREunload(void) {}
  64.                         
  65. void Cenviron( void)
  66. {
  67.     DialogPtr    dptr;
  68.     short         ditem;
  69.     Str255        scratchPstring;
  70.     long         scratchlong;
  71.     OSType        newtype;
  72.     
  73.     dptr = GetNewMySmallStrangeDialog( PrefDLOG, NULL, kInFront, (void *)ThirdCenterDialog);    
  74.     
  75.     SetCntrl(dptr, PrefDClose, gApplicationPrefs->WindowsDontGoAway);
  76.     SetCntrl(dptr, PrefStag, gApplicationPrefs->StaggerWindows);
  77.     SetCntrl(dptr, PrefCMDkey, gApplicationPrefs->CommandKeys);
  78.     SetCntrl(dptr, PrefTMap, gApplicationPrefs->RemapTilde);
  79.     SetCntrl(dptr, PrefBlink, gApplicationPrefs->BlinkCursor);
  80.     
  81.     SetCntrl(dptr, PrefBlockCursor, (gApplicationPrefs->CursorType == 0));
  82.     SetCntrl(dptr, PrefUnderscoreCursor, (gApplicationPrefs->CursorType == 1));
  83.     SetCntrl(dptr, PrefVerticalCursor, (gApplicationPrefs->CursorType == 2));
  84.  
  85.     scratchPstring[0] = 4;
  86.     BlockMove(&(gApplicationPrefs->CaptureFileCreator), &scratchPstring[1], sizeof(OSType));
  87.     SetTEText(dptr, PrefCaptTE, scratchPstring);
  88.     newtype = gApplicationPrefs->CaptureFileCreator;
  89.  
  90.     scratchlong = gApplicationPrefs->CopyTableThresh;
  91.     NumToString(scratchlong, scratchPstring);
  92.     SetTEText(dptr, PrefCTt, scratchPstring);
  93.     SelIText(dptr, PrefCTt, 0, 32767);
  94.  
  95.     NumToString(gApplicationPrefs->TimeSlice, scratchPstring);
  96.     SetTEText(dptr, PrefTimeSlice, scratchPstring);
  97.  
  98.     ShowWindow(dptr);
  99.     ditem=0;                                /* initially no hits */
  100.     while((ditem>2) || (ditem==0)) {    
  101.         ModalDialog(DLOGwOK_CancelUPP,&ditem);
  102.         switch(ditem) {
  103.             case PrefDClose:
  104.             case PrefStag:
  105.             case PrefCMDkey:
  106.             case PrefTMap:
  107.             case PrefBlink:
  108.                 FlipCheckBox( dptr, ditem);
  109.                 break;
  110.  
  111.             case PrefBlockCursor:
  112.                 SetCntrl(dptr, PrefBlockCursor, 1);
  113.                 SetCntrl(dptr, PrefUnderscoreCursor, 0);
  114.                 SetCntrl(dptr, PrefVerticalCursor, 0);
  115.                 break;
  116.             case PrefUnderscoreCursor:
  117.                 SetCntrl(dptr, PrefBlockCursor, 0);
  118.                 SetCntrl(dptr, PrefUnderscoreCursor, 1);
  119.                 SetCntrl(dptr, PrefVerticalCursor, 0);
  120.                 break;
  121.             case PrefVerticalCursor:
  122.                 SetCntrl(dptr, PrefBlockCursor, 0);
  123.                 SetCntrl(dptr, PrefUnderscoreCursor, 0);
  124.                 SetCntrl(dptr, PrefVerticalCursor, 1);
  125.                 break;
  126.  
  127.             case PrefCaptCreat:
  128.                 GetApplicationType(&newtype);
  129.                 scratchPstring[0] = 4;
  130.                 BlockMove(&newtype, &scratchPstring[1], sizeof(OSType));
  131.                 SetTEText(dptr, PrefCaptTE, scratchPstring);
  132.             default:
  133.                 break;
  134.             } /* switch */
  135.         }
  136.     
  137.     if (ditem==DLOGCancel) {
  138.             DisposDialog( dptr);
  139.             return;
  140.             }
  141.  
  142.     GetTEText(dptr, PrefCTt, scratchPstring);
  143.     StringToNum(scratchPstring, &scratchlong);
  144.     gApplicationPrefs->CopyTableThresh = (short) scratchlong;
  145.  
  146.     GetTEText(dptr, PrefTimeSlice, scratchPstring);
  147.     StringToNum(scratchPstring, &scratchlong);
  148.     BoundsCheck(&scratchlong, 100, 2);
  149.     gApplicationPrefs->TimeSlice = scratchlong;
  150.  
  151.     GetTEText(dptr, PrefCaptTE, scratchPstring);
  152.     BlockMove(&scratchPstring[1], &(gApplicationPrefs->CaptureFileCreator), sizeof(OSType));
  153.  
  154.     gApplicationPrefs->CommandKeys = GetCntlVal(dptr, PrefCMDkey);                    
  155.     gApplicationPrefs->WindowsDontGoAway = GetCntlVal(dptr, PrefDClose);
  156.     gApplicationPrefs->RemapTilde =    GetCntlVal(dptr, PrefTMap);
  157.     gApplicationPrefs->StaggerWindows = GetCntlVal(dptr, PrefStag);
  158.     gApplicationPrefs->BlinkCursor = GetCntlVal(dptr, PrefBlink);
  159.     gApplicationPrefs->CursorType = (GetCntlVal(dptr, PrefUnderscoreCursor) == 1) + (2 *
  160.                                      (GetCntlVal(dptr, PrefVerticalCursor) == 1));
  161.                                      
  162.     switchMenus(gApplicationPrefs->CommandKeys);
  163.     SavePreferences();
  164.     
  165.     DisposDialog( dptr);
  166. }
  167.  
  168. void Cftp(void)
  169. {
  170.     DialogPtr            dptr;
  171.     short                ditem;
  172.     Str255                scratchPstring;
  173.     OSType                scratchOSType;
  174.     SFReply                sfr;
  175.     FInfo                fi;            
  176.     Point                where = {100,100};
  177.     
  178.     dptr = GetNewMySmallStrangeDialog( FTPDLOG, NULL, kInFront, (void *)ThirdCenterDialog);    
  179.  
  180.     SetCntrl(dptr, FTPServerOff, (gFTPServerPrefs->ServerState == 0));
  181.     SetCntrl(dptr, FTPServerUnsecure, (gFTPServerPrefs->ServerState == 1));
  182.     SetCntrl(dptr, FTPServerPswdPlease, (gFTPServerPrefs->ServerState == 2));
  183.     SetCntrl(dptr, FTPShowFTPlog, gFTPServerPrefs->ShowFTPlog);
  184.     SetCntrl(dptr, FTPrevDNS, gFTPServerPrefs->DNSlookupconnections);
  185.     SetCntrl(dptr, FTPUseMacBinaryII, gFTPServerPrefs->UseMacBinaryII);
  186.     SetCntrl(dptr, FTPResetMacBinary, gFTPServerPrefs->ResetMacBinary);
  187.     SetCntrl(dptr, FTPISO, gFTPServerPrefs->DoISOtranslation);
  188.  
  189.     HideDItem(dptr, FTPrevDNS);        // Sometime later, perhaps.
  190.     
  191.     scratchPstring[0] = 4;
  192.  
  193.     BlockMove(&(gFTPServerPrefs->BinaryCreator), &scratchPstring[1], sizeof(OSType));
  194.     SetTEText(dptr, FTPbincreatTE, scratchPstring);
  195.     
  196.     BlockMove(&(gFTPServerPrefs->BinaryType), &scratchPstring[1], sizeof(OSType));
  197.     SetTEText(dptr, FTPbintypeTE, scratchPstring);
  198.     SelIText(dptr, FTPbintypeTE, 0, 32767);
  199.  
  200.     BlockMove(&(gFTPServerPrefs->TextCreator), &scratchPstring[1], sizeof(OSType));
  201.     SetTEText(dptr, FTPtextcreatTE, scratchPstring);
  202.  
  203.     ShowWindow(dptr);
  204.     ditem=0;                                    /* initially no hits */
  205.     while((ditem>2) || (ditem==0)) {    
  206.         ModalDialog(DLOGwOK_CancelUPP,&ditem);
  207.         switch(ditem) {
  208.             case    FTPShowFTPlog:
  209.             case    FTPrevDNS:
  210.             case    FTPUseMacBinaryII:
  211.             case    FTPResetMacBinary:
  212.             case    FTPISO:
  213.                 FlipCheckBox( dptr, ditem);
  214.                 break;
  215.  
  216.             case    FTPServerOff:
  217.                 SetCntrl(dptr, FTPServerOff, 1);
  218.                 SetCntrl(dptr, FTPServerUnsecure, 0);
  219.                 SetCntrl(dptr, FTPServerPswdPlease, 0);
  220.                 break;
  221.             case    FTPServerUnsecure:
  222.                 SetCntrl(dptr, FTPServerOff, 0);
  223.                 SetCntrl(dptr, FTPServerUnsecure, 1);
  224.                 SetCntrl(dptr, FTPServerPswdPlease, 0);
  225.                 break;
  226.             case    FTPServerPswdPlease:
  227.                 SetCntrl(dptr, FTPServerOff, 0);
  228.                 SetCntrl(dptr, FTPServerUnsecure, 0);
  229.                 SetCntrl(dptr, FTPServerPswdPlease, 1);
  230.                 break;
  231.  
  232.             case    FTPtextcreatorbutton:
  233.                 if (GetApplicationType(&scratchOSType)) {
  234.                     BlockMove(&scratchOSType, &scratchPstring[1], sizeof(OSType));
  235.                     SetTEText(dptr, FTPtextcreatTE, scratchPstring);
  236.                     }
  237.                 break;
  238.             
  239.             case    FTPbinexamplebutton:
  240.                 SFGetFile(where, NULL, NULL, -1, NULL, NULL, &sfr);
  241.                 if (sfr.good) {
  242.                     GetFInfo(sfr.fName, sfr.vRefNum, &fi);
  243.                     scratchPstring[0] = sizeof(OSType);
  244.                     BlockMove(&fi.fdCreator, &scratchPstring[1], sizeof(OSType));
  245.                     SetTEText(dptr, FTPbincreatTE, scratchPstring);
  246.                     BlockMove(&fi.fdType, &scratchPstring[1], sizeof(OSType));
  247.                     SetTEText(dptr, FTPbintypeTE, scratchPstring);
  248.                     }
  249.                 break;    
  250.             default:
  251.                 break;
  252.             } /* switch */
  253.         } /* while */
  254.     
  255.     if (ditem==DLOGCancel) {
  256.             DisposDialog( dptr);
  257.             return;
  258.             }
  259.  
  260.     gFTPServerPrefs->ServerState = GetCntlVal(dptr, FTPServerUnsecure) + 
  261.         GetCntlVal(dptr, FTPServerPswdPlease) * 2;
  262.     StartUpFTP();            // Make sure FTP server recognizes new mode.
  263.     
  264.     gFTPServerPrefs->ShowFTPlog = GetCntlVal(dptr, FTPShowFTPlog);
  265.     gFTPServerPrefs->DNSlookupconnections = GetCntlVal(dptr, FTPrevDNS);
  266.     gFTPServerPrefs->UseMacBinaryII = GetCntlVal(dptr, FTPUseMacBinaryII);
  267.     gFTPServerPrefs->ResetMacBinary = GetCntlVal(dptr, FTPResetMacBinary);
  268.     gFTPServerPrefs->DoISOtranslation = GetCntlVal(dptr, FTPISO);
  269.  
  270.     GetTEText(dptr, FTPbincreatTE, scratchPstring);
  271.     BlockMove(&scratchPstring[1], &(gFTPServerPrefs->BinaryCreator), sizeof(OSType));
  272.     
  273.     GetTEText(dptr, FTPbintypeTE, scratchPstring);
  274.     BlockMove(&scratchPstring[1], &(gFTPServerPrefs->BinaryType), sizeof(OSType));
  275.  
  276.     GetTEText(dptr, FTPtextcreatTE, scratchPstring);
  277.     BlockMove(&scratchPstring[1], &(gFTPServerPrefs->TextCreator), sizeof(OSType));
  278.  
  279.     SavePreferences();
  280.     
  281.     DisposDialog( dptr);
  282. }
  283.  
  284. Boolean GetApplicationType(OSType *type)
  285. {
  286.     SFTypeList types;
  287.     SFReply sfr;
  288.     FInfo fi;
  289.     Point where;
  290.     
  291.     SetPt(&where, 100, 100);
  292.     types[0] = 'APPL';
  293.     SFGetFile(where, NULL, NULL, 1, types, NULL, &sfr);
  294.     if (sfr.good) {
  295.         GetFInfo(sfr.fName, sfr.vRefNum, &fi);
  296.         BlockMove(&fi.fdCreator, type, sizeof(OSType));        // Copy the application creator type
  297.         }
  298.         
  299.     return(sfr.good);
  300. }
  301.  
  302. //    Our standard modal dialog filter with code for handling user items containing lists.
  303. SIMPLE_UPP(MyDlogWListFilter, ModalFilter);
  304. pascal short MyDlogWListFilter( DialogPtr dptr, EventRecord *evt, short *item)
  305. {
  306.     short keyCode, key, iType;
  307.     Handle iHndl;
  308.     Rect iRect;
  309.     Point scratchPoint;
  310.  
  311.     SetPort(dptr);
  312.     if (evt->what == keyDown) {
  313.         key = evt->message & charCodeMask;
  314.         keyCode = (evt->message >>8) & 0xff ;
  315.         if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter
  316.             *item = 1;                // ok
  317.             FlashButton(dptr, 1);
  318.             return(-1);
  319.             }
  320.         }
  321.     else if (evt->what == updateEvt) {
  322.         if ((WindowPtr)evt->message == dptr) {
  323.             GetDItem(dptr,1,&iType,&iHndl,&iRect);    // ok
  324.             PenSize(3,3);
  325.             InsetRect(&iRect,-4,-4);
  326.             FrameRoundRect(&iRect,16,16);
  327.             }
  328.     }
  329.     
  330.     if (evt->what == mouseDown) {
  331.         GetDItem(dptr, kItemList, &iType, &iHndl, &iRect);
  332.         scratchPoint = evt->where;
  333.         GlobalToLocal(&scratchPoint);
  334.         if (PtInRect(scratchPoint, &iRect)) {
  335.             *item = kItemList;
  336.             if (LClick(scratchPoint, evt->modifiers, (ListHandle)GetWRefCon(dptr))) {
  337.                 *item = kChange;
  338.                 FlashButton(dptr, kChange);
  339.                 }    
  340.             return(-1);
  341.         }
  342.     }
  343.     
  344.     return(FALSE);
  345. }
  346.  
  347. //    User Dialog Item Procedure for a list.  Assumes the Dialog's refcon contains the list
  348. //    handle.
  349. SIMPLE_UPP(listDitemproc, UserItem);
  350. pascal listDitemproc(DialogPtr theDlg, short itemNo)
  351. {
  352.     short        itemType;
  353.     Handle        ControlHndl;
  354.     Rect        scratchRect;
  355.     
  356.     GetDItem(theDlg, itemNo, &itemType, &ControlHndl, &scratchRect);
  357.     
  358.     PenNormal();
  359.     InsetRect(&scratchRect, -1, -1);
  360.     FrameRect(&scratchRect);
  361.     LUpdate(theDlg->visRgn, (ListHandle)GetWRefCon(theDlg));
  362. }
  363.  
  364. void    BoundsCheck(long *value, long high, long low)
  365. {
  366.     if (*value > high) *value = high;
  367.     if (*value < low) *value = low;
  368. }
  369.  
  370. void    EditConfigType(ResType ConfigResourceType, Boolean (*EditFunction)(StringPtr))
  371. {
  372.     DialogPtr    dptr;
  373.     Handle         iHndl;
  374.     short         iType, length, ditem, numberofitems, index, resID;
  375.     Rect         ListBox, ListBounds;
  376.     Point         cellSize, theCell;
  377.     ListHandle    thelist;
  378.     Handle        ItemResource;
  379.     Str255        ItemName;
  380.     ResType        restype;
  381.  
  382.     dptr = GetNewMySmallDialog(kItemDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  383.     ditem = 3;
  384.  
  385.     GetDItem(dptr, kItemList, &iType, &iHndl, &ListBox);
  386.     SetDItem(dptr, kItemList, iType, (Handle)listDitemprocUPP, &ListBox);
  387.     
  388.  
  389.     ListBox.right -= 15;        // Make room for scrollbar
  390.     SetRect(&ListBounds, 0,0,1,0);
  391.     SetPt(&cellSize,(ListBox.right-ListBox.left),16);
  392.     thelist = LNew(&ListBox, &ListBounds, cellSize, 0, (WindowPtr)dptr,0,0,0,1);
  393. #define kSCListMods lNoNilHilite+lOnlyOne
  394.     (*(thelist))->listFlags = kSCListMods;
  395.     
  396.     SetWRefCon(dptr, (long)thelist);        // So the Ditem proc can find the list
  397.     
  398.     UseResFile(TelInfo->SettingsFile);
  399.     numberofitems = Count1Resources(ConfigResourceType);
  400.     
  401.     for(index = 1, theCell.v = 0, theCell.h = 0; index <= numberofitems;
  402.                  index++, theCell.v++) {
  403.         ItemResource = Get1IndResource(ConfigResourceType, index);
  404.         GetResInfo(ItemResource, &resID, &restype, (StringPtr)&ItemName);
  405.         LAddRow(1,-1, thelist);
  406.         LSetCell(ItemName+1, Length(ItemName), theCell, thelist);
  407.         ReleaseResource(ItemResource);
  408.         }
  409.         
  410.     theCell.v = 0;
  411.     theCell.h = 0;
  412.     if (numberofitems) LSetSelect(1, theCell, thelist);
  413.     LDoDraw(1, thelist);
  414. //    LUpdate(dptr->visRgn, thelist); Is this needed?
  415.     
  416.     while (ditem > 1) {
  417.         ModalDialog(MyDlogWListFilterUPP, &ditem);
  418.         
  419.         switch(ditem) {
  420.             case kRemove:
  421.                 SetPt(&theCell, 0, 0);
  422.                 if (LGetSelect(TRUE, &theCell, thelist)) {
  423.                     length = 254;
  424.                     LGetCell(ItemName+1, &length, theCell, thelist);
  425.                     ItemName[0] = (char)length;
  426.                     if (!(EqualString(ItemName, "\p<Default>", TRUE, FALSE))) {
  427.                         LDelRow(1,theCell.v,thelist);
  428.                         UseResFile(TelInfo->SettingsFile);
  429.                         ItemResource = Get1NamedResource(ConfigResourceType, ItemName);
  430.                         RmveResource(ItemResource);
  431.                         ReleaseResource(ItemResource);
  432.                         UpdateResFile(TelInfo->SettingsFile);
  433.                         }
  434.                     }
  435.             break;
  436.             
  437.             case kChange:
  438.                 SetPt(&theCell, 0, 0);
  439.                 if (LGetSelect(TRUE, &theCell, thelist)) {
  440.                     length = 254;
  441.                     LGetCell(ItemName+1, &length, theCell, thelist);
  442.                     ItemName[0] = (char)length;
  443.                     if ((*EditFunction)((StringPtr)&ItemName)) {
  444.                         LSetCell(ItemName+1, Length(ItemName), theCell, thelist);
  445.                     }
  446.                 }
  447.             break;
  448.             
  449.             case kNew:        
  450.                 ItemName[0] = 0;                    // Signal new shortcut
  451.                 if ((*EditFunction)((StringPtr)&ItemName)) {
  452.                     theCell.v = LAddRow(1, -1, thelist);
  453.                     LSetCell(ItemName+1, Length(ItemName), theCell, thelist);
  454.                 }
  455.             break;
  456.         } // switch
  457.         
  458.         SetPt(&theCell, 0, 0);
  459.         if (LGetSelect(TRUE, &theCell, thelist)) {
  460.             Hilite(dptr, kRemove, 0);
  461.             Hilite(dptr, kChange, 0);
  462.             }
  463.         else {
  464.             Hilite(dptr, kRemove, 255);
  465.             Hilite(dptr, kChange, 255);
  466.             }
  467.         
  468.     } // while
  469.     
  470.     LDispose(thelist);
  471.     DisposDialog(dptr);
  472. }
  473.  
  474. void ZeroNumOnly(void)
  475. {
  476.     short i;
  477.     
  478.     for(i=0; i<NUMONLYSIZE; i++) NumOnly[i]=0;
  479. }
  480.  
  481. Boolean InNumOnly(short item)
  482. {
  483.     short index = 1;
  484.     
  485.     while ((NumOnly[index] != item) && (NumOnly[index] != 0)) index++;
  486.     
  487.     return(NumOnly[index] == item);
  488. }
  489.  
  490. short        NumberOfColorBoxes;
  491. short        BoxColorItems[8];
  492. RGBColor    BoxColorData[8];
  493.  
  494. SIMPLE_UPP(ColorBoxItemProc, UserItem);
  495. pascal ColorBoxItemProc(DialogPtr theDlg, short itemNo)
  496. {
  497.     short        itemType, index = 0;
  498.     Handle        ControlHndl;
  499.     Rect        scratchRect;
  500.     RGBColor    rgb;
  501.  
  502.     GetDItem(theDlg, itemNo, &itemType, &ControlHndl, &scratchRect);
  503.     PenNormal();
  504.     FrameRect(&scratchRect);
  505.     InsetRect(&scratchRect, 1, 1);            // Why isn't this framing the boxes?
  506.     
  507.     GetForeColor(&rgb);
  508.  
  509.     while ((index < NumberOfColorBoxes) && (BoxColorItems[index] != itemNo)) index++;
  510.     
  511.     RGBForeColor(&BoxColorData[index]);        /* color corresponding to item */
  512.     PaintRect(&scratchRect);
  513.  
  514.     RGBForeColor(&rgb);            /* restore previous foreground color */
  515. }
  516.  
  517. SIMPLE_UPP(ColorBoxModalProc, ModalFilter);
  518. pascal short ColorBoxModalProc( DialogPtr dptr, EventRecord *evt, short *item)
  519. {
  520.     short keyCode, key, iType, index;
  521.     Handle    iHndl;
  522.     Rect    iRect;
  523.     
  524.     if ((evt->what == keyDown) || (evt->what == autoKey)) {
  525.         key = evt->message & charCodeMask;
  526.         keyCode = (evt->message >>8) & 0xff;
  527.         if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter
  528.             *item = DLOGOk;
  529.             return(-1);                /* BYU LSC - pascal doesn't like "1" as true */
  530.             }
  531.         if (((key == '.') && (evt->modifiers & cmdKey)) ||
  532.             ((key == 0x1b) && (keyCode == 0x35)) ) {    // 0x35 == escKey
  533.             *item = DLOGCancel;
  534.             return(-1);                /* BYU LSC - pascal doesn't like "1" as true */
  535.             }
  536.  
  537.         if ((key < '0' || key > '9') && 
  538.             !(key == 0x08 || key == 0x09 || (key > 0x1B && key < 0x20))
  539.             && InNumOnly(((DialogPeek)dptr)->editField + 1)) {
  540.                 /* Reject non-numbers for this TE */
  541.                 *item = NumOnly[0];    /* Kludge -- Return "safe" item */
  542.                 return(-1);
  543.                 }   
  544.            }
  545.            
  546.     if (evt->what == updateEvt) {
  547.         if ((WindowPtr)evt->message == dptr) {
  548.             GetDItem(dptr,DLOGOk,&iType,&iHndl,&iRect);    // ok
  549.             PenSize(3,3);
  550.             InsetRect(&iRect,-4,-4);
  551.             FrameRoundRect(&iRect,16,16);
  552.             for (index = 0; index < NumberOfColorBoxes; index++)
  553.                 ColorBoxItemProc(dptr, BoxColorItems[index]);        // update color boxes
  554.             }
  555.     }
  556.     
  557.     Stask();
  558.     return(FALSE);
  559. }
  560.  
  561. SIMPLE_UPP(TerminalModalProc, ModalFilter);
  562. pascal short TerminalModalProc( DialogPtr dptr, EventRecord *evt, short *item)
  563. {
  564.     if (evt->what == mouseDown) return(PopupMousedown(dptr, evt, item));
  565.  
  566.     return(ColorBoxModalProc(dptr, evt, item));
  567. }
  568.  
  569. SIMPLE_UPP(SessionModalProc, ModalFilter);
  570. pascal short SessionModalProc(DialogPtr dptr, EventRecord *evt, short *item)
  571. {
  572.     if ((evt->what == keyDown) || (evt->what == autoKey))
  573.         if ((evt->message & charCodeMask) == ' ') {
  574.             *item = NumOnly[0];    /* Kludge -- Return "safe" item */
  575.             return(-1);
  576.             }
  577.     
  578.     return(TerminalModalProc(dptr, evt, item));
  579. }
  580.  
  581. Boolean EditTerminal(StringPtr PrefRecordNamePtr)
  582. {
  583.     DialogPtr        dptr;
  584.     short            ditem, scratchshort, resourceID;
  585.     long            scratchlong;
  586.     ResType            scratchResType;
  587.     Boolean            IsNewPrefRecord, UserLikesNewColor;
  588.     TerminalPrefs**    TermPrefsHdl;
  589.     TerminalPrefs*    TermPrefsPtr;
  590.     Str255            scratchPstring;
  591.     RGBColor        scratchRGBcolor;
  592.     Point            ColorBoxPoint;
  593.     MenuHandle        WeNeedAFontMenuHandle;
  594.     popup TPopup[] = {{TermFontPopup, (MenuHandle) 0, 1},
  595.                         {0, (MenuHandle) 0, 0}};
  596.  
  597.     dptr = GetNewMySmallStrangeDialog(TermDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  598.     ditem = 3;
  599.     
  600.     WeNeedAFontMenuHandle = NewMenu(666, "\p");
  601.     AddResMenu(WeNeedAFontMenuHandle, 'FONT');
  602.     TPopup[0].h = WeNeedAFontMenuHandle;
  603.     PopupInit(dptr, TPopup);
  604.     
  605.     if (PrefRecordNamePtr[0] != 0) {
  606.         IsNewPrefRecord = FALSE;
  607.         UseResFile(TelInfo->SettingsFile);
  608.         TermPrefsHdl = (TerminalPrefs **)Get1NamedResource(TERMINALPREFS_RESTYPE, PrefRecordNamePtr);
  609.         if (EqualString(PrefRecordNamePtr, "\p<Default>", FALSE, FALSE)) {
  610.             HideDItem(dptr, TermNameStatText);
  611.             HideDItem(dptr, TermName);
  612.             }
  613.         }
  614.     else {
  615.         TermPrefsHdl = GetDefaultTerminal();
  616.         IsNewPrefRecord = TRUE;
  617.         GetIndString(PrefRecordNamePtr, MISC_STRINGS, MISC_NEWTERM);
  618.         }
  619.  
  620.     HLock((Handle) TermPrefsHdl);
  621.     TermPrefsPtr = *TermPrefsHdl;
  622.     SetTEText(dptr, TermName, PrefRecordNamePtr);
  623.     SetCntrl(dptr, TermANSI, TermPrefsPtr->ANSIgraphics);
  624.     HideDItem(dptr, TermANSI);                // Perhaps later
  625.     SetCntrl(dptr, TermXterm, TermPrefsPtr->Xtermsequences);
  626.     SetCntrl(dptr, Termvtwrap, TermPrefsPtr->vtwrap);
  627.     SetCntrl(dptr, Termmeta, TermPrefsPtr->emacsmetakey);
  628.     SetCntrl(dptr, Termarrow, TermPrefsPtr->emacsarrows);
  629.     SetCntrl(dptr, TermMAT, TermPrefsPtr->MATmappings);
  630.     SetCntrl(dptr, Termeightbit, TermPrefsPtr->eightbit);
  631.     SetCntrl(dptr, Termclearsave, TermPrefsPtr->clearsave);
  632.     SetCntrl(dptr, TermVT100, (TermPrefsPtr->vtemulation == 0));
  633.     SetCntrl(dptr, TermVT220, (TermPrefsPtr->vtemulation == 1));
  634.     scratchlong = (long)(TermPrefsPtr->vtwidth);
  635.     NumToString(scratchlong, scratchPstring);
  636.     SetTEText(dptr, TermWidth, scratchPstring);
  637.     scratchlong = (short)(TermPrefsPtr->vtheight);
  638.     NumToString(scratchlong, scratchPstring);
  639.     SetTEText(dptr, TermHeight, scratchPstring);
  640.     scratchlong = TermPrefsPtr->fontsize;
  641.     NumToString(scratchlong, scratchPstring);
  642.     SetTEText(dptr, TermFontSize, scratchPstring);
  643.     scratchlong = TermPrefsPtr->numbkscroll;
  644.     NumToString(scratchlong, scratchPstring);
  645.     SetTEText(dptr, TermScrollback, scratchPstring);
  646.     SetTEText(dptr, TermAnswerback, TermPrefsPtr->AnswerBackMessage);
  647.     
  648.     for(scratchshort = CountMItems(TPopup[0].h); scratchshort; scratchshort--) {
  649.         GetItem(TPopup[0].h, scratchshort, scratchPstring);
  650.         if (EqualString(scratchPstring, (TermPrefsPtr->DisplayFont), TRUE, FALSE))
  651.             TPopup[0].choice = scratchshort;
  652.         }
  653.     
  654.     ZeroNumOnly();
  655.     NumOnly[0] = TermSafeItem;
  656.     NumOnly[1] = TermWidth; NumOnly[2] = TermHeight; NumOnly[3] = TermFontSize;
  657.     NumOnly[4] = TermScrollback;  NumOnly[5] = 0;
  658.     
  659.     if (theWorld.hasColorQD) {
  660.         for (scratchshort = 0, NumberOfColorBoxes = 4; scratchshort < NumberOfColorBoxes; scratchshort++) {
  661.             BoxColorItems[scratchshort] = TermNFcolor + scratchshort;
  662.             BlockMove(&(TermPrefsPtr->nfcolor) + scratchshort,
  663.                 &BoxColorData[scratchshort], sizeof(RGBColor));
  664.             UItemAssign( dptr, TermNFcolor + scratchshort, ColorBoxItemProcUPP);
  665.             }
  666.         }
  667.     else
  668.         NumberOfColorBoxes = 0;        // B&W machine
  669.         
  670.     ColorBoxPoint.h = 0;            // Have the color picker center the box on the main
  671.     ColorBoxPoint.v = 0;            // screen
  672.         
  673.     SelIText(dptr, TermName, 0, 32767);
  674.     ShowWindow(dptr);
  675.     
  676.     while (ditem > 2) {
  677.         ModalDialog(TerminalModalProcUPP, &ditem);
  678.         switch (ditem) {
  679.             case    TermANSI:
  680.             case    TermXterm:
  681.             case    Termvtwrap:
  682.             case    Termmeta:
  683.             case    Termarrow:
  684.             case    TermMAT:
  685.             case    Termeightbit:
  686.             case    Termclearsave:
  687.                 FlipCheckBox(dptr, ditem);
  688.                 break;
  689.             
  690.             case    TermVT100:
  691.             case    TermVT220:
  692.                 FlipRadioButton(dptr, TermVT100);
  693.                 FlipRadioButton(dptr, TermVT220);
  694.                 if (ditem == TermVT100)
  695.                     SetTEText(dptr, TermAnswerback, "\pVT100");
  696.                 else
  697.                     SetTEText(dptr, TermAnswerback, "\pVT220");
  698.                 break;
  699.             
  700.             case    TermNFcolor:    
  701.             case    TermNBcolor:    
  702.             case    TermBFcolor:    
  703.             case    TermBBcolor:    
  704.                 if (theWorld.hasColorQD) {
  705.                     UserLikesNewColor = GetColor(ColorBoxPoint, "\pPlease Select New Color",
  706.                          &BoxColorData[ditem-TermNFcolor], &scratchRGBcolor);
  707.                     if (UserLikesNewColor)
  708.                         BoxColorData[ditem-TermNFcolor] = scratchRGBcolor;
  709.                     }
  710.                 break;
  711.                 
  712.             default:
  713.                 break;
  714.             
  715.             } // switch
  716.         } // while
  717.             
  718.     GetItem(TPopup[0].h, TPopup[0].choice, scratchPstring);
  719.     PopupCleanup();
  720.     
  721.     if (ditem == 2) {
  722.         if (IsNewPrefRecord) DisposeHandle((Handle) TermPrefsHdl);
  723.         else ReleaseResource((Handle) TermPrefsHdl);
  724.         
  725.         DisposeDialog(dptr);
  726.         return(FALSE);            // No changes should be made.
  727.         }
  728.     
  729.         
  730.     if (theWorld.hasColorQD) {
  731.         for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) {
  732.                 BlockMove(&BoxColorData[scratchshort], 
  733.                     &(TermPrefsPtr->nfcolor) + scratchshort, sizeof(RGBColor));
  734.             }
  735.         }
  736.         
  737.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  738.     BlockMove(scratchPstring, (TermPrefsPtr->DisplayFont), scratchPstring[0]+1);
  739.     
  740.     TermPrefsPtr->ANSIgraphics = GetCntlVal(dptr, TermANSI);
  741.     TermPrefsPtr->Xtermsequences = GetCntlVal(dptr, TermXterm);
  742.     TermPrefsPtr->vtwrap = GetCntlVal(dptr, Termvtwrap);
  743.     TermPrefsPtr->emacsmetakey = GetCntlVal(dptr, Termmeta);
  744.     TermPrefsPtr->emacsarrows = GetCntlVal(dptr, Termarrow);
  745.     TermPrefsPtr->MATmappings = GetCntlVal(dptr, TermMAT);
  746.     TermPrefsPtr->eightbit = GetCntlVal(dptr, Termeightbit);
  747.     TermPrefsPtr->clearsave = GetCntlVal(dptr, Termclearsave);
  748.     
  749.     TermPrefsPtr->vtemulation = (GetCntlVal(dptr, TermVT220) != 0);
  750.  
  751.     GetTEText(dptr, TermWidth, scratchPstring);
  752.     StringToNum(scratchPstring, &scratchlong);
  753.     BoundsCheck(&scratchlong, 133, 10);
  754.     TermPrefsPtr->vtwidth = (short) scratchlong;
  755.     
  756.     GetTEText(dptr, TermHeight, scratchPstring);
  757.     StringToNum(scratchPstring, &scratchlong);
  758.     BoundsCheck(&scratchlong, 80, 10);
  759.     TermPrefsPtr->vtheight = (short) scratchlong;
  760.  
  761.     GetTEText(dptr, TermFontSize, scratchPstring);
  762.     StringToNum(scratchPstring, &scratchlong);
  763.     BoundsCheck(&scratchlong, 24, 4);
  764.     TermPrefsPtr->fontsize = (short) scratchlong;
  765.  
  766.     GetTEText(dptr, TermScrollback, scratchPstring);
  767.     StringToNum(scratchPstring, &scratchlong);
  768.     BoundsCheck(&scratchlong, 50000, 24);
  769.     TermPrefsPtr->numbkscroll = (short) scratchlong;
  770.  
  771.     GetTEText(dptr, TermAnswerback, scratchPstring);
  772.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  773.     BlockMove(scratchPstring, TermPrefsPtr->AnswerBackMessage, scratchPstring[0]+1);
  774.     
  775.     GetTEText(dptr, TermName, PrefRecordNamePtr);
  776.     
  777.     if (IsNewPrefRecord) {
  778.         UseResFile(TelInfo->SettingsFile);
  779.         resourceID = UniqueID(TERMINALPREFS_RESTYPE);
  780.         AddResource((Handle)TermPrefsHdl, TERMINALPREFS_RESTYPE, resourceID, PrefRecordNamePtr);
  781.         UpdateResFile(TelInfo->SettingsFile);
  782.         ReleaseResource((Handle)TermPrefsHdl);
  783.         }
  784.     else {
  785.         UseResFile(TelInfo->SettingsFile);
  786.         GetResInfo((Handle)TermPrefsHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring);
  787.         SetResInfo((Handle)TermPrefsHdl, resourceID, PrefRecordNamePtr);
  788.         ChangedResource((Handle)TermPrefsHdl);
  789.         UpdateResFile(TelInfo->SettingsFile);
  790.         ReleaseResource((Handle)TermPrefsHdl);
  791.         }
  792.     
  793.     DisposeDialog(dptr);
  794.     return(TRUE);            // A resource has changed or been added.    
  795. }
  796.  
  797. Boolean EditSession(StringPtr PrefRecordNamePtr)
  798. {
  799.     DialogPtr        dptr;
  800.     short            ditem, scratchshort, resourceID;
  801.     long            scratchlong;
  802.     ResType            scratchResType;
  803.     Boolean            IsNewPrefRecord;
  804.     SessionPrefs**    SessPrefsHdl;
  805.     SessionPrefs*    SessPrefsPtr;
  806.     Str255            scratchPstring, scratchPstring2;
  807.     popup SPopup[] = {{SessTermPopup, (MenuHandle) 0, 1},
  808.                         {SessTransTablePopup, (MenuHandle) 0, 1},
  809.                         {0, (MenuHandle) 0, 0}};
  810.  
  811.     dptr = GetNewMySmallStrangeDialog(SessionConfigDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  812.     ditem = 3;
  813.         
  814.     SPopup[0].h = NewMenu(666, "\p");
  815.     UseResFile(TelInfo->SettingsFile);
  816.     AddResMenu(SPopup[0].h, TERMINALPREFS_RESTYPE);
  817.     EnableItem(SPopup[0].h, 0);        // Make sure the entire menu is enabled
  818.     
  819.     SPopup[1].h = NewMenu(667, "\p");
  820.     AppendMenu(SPopup[1].h, "\pNone");
  821.     AddResMenu(SPopup[1].h, USER_TRSL);
  822.     EnableItem(SPopup[1].h, 0);        // Make sure the entire menu is enabled
  823.  
  824.     PopupInit(dptr, SPopup);
  825.     
  826.     if (PrefRecordNamePtr[0] != 0) {
  827.         IsNewPrefRecord = FALSE;
  828.         UseResFile(TelInfo->SettingsFile);
  829.         SessPrefsHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, PrefRecordNamePtr);
  830.         if (EqualString(PrefRecordNamePtr, "\p<Default>", FALSE, FALSE)) {
  831.             HideDItem(dptr, SessAlias);
  832.             HideDItem(dptr, SessAliasStatText);
  833.             }
  834.         }
  835.     else {
  836.         SessPrefsHdl = GetDefaultSession();
  837.         IsNewPrefRecord = TRUE;
  838.         GetIndString(PrefRecordNamePtr, MISC_STRINGS, MISC_NEWSESSION);
  839.         }
  840.         
  841.     HLock((Handle) SessPrefsHdl);
  842.     SessPrefsPtr = *SessPrefsHdl;
  843.     SetCntrl(dptr, SessTEKinhib, (SessPrefsPtr->tektype == -1));
  844.     SetCntrl(dptr, SessTEK4014, (SessPrefsPtr->tektype == 0));
  845.     SetCntrl(dptr, SessTEK4105, (SessPrefsPtr->tektype == 1));
  846.     SetCntrl(dptr, SessPasteQuick, (SessPrefsPtr->pastemethod == 0));
  847.     SetCntrl(dptr, SessPasteBlock, (SessPrefsPtr->pastemethod == 1));
  848.     SetCntrl(dptr, SessDeleteDel, (SessPrefsPtr->bksp == 1));
  849.     SetCntrl(dptr, SessDeleteBS, (SessPrefsPtr->bksp == 0));
  850.     SetCntrl(dptr, SessForceSave, SessPrefsPtr->forcesave);
  851.     SetCntrl(dptr, SessBezerkeley, SessPrefsPtr->crmap);
  852.     SetCntrl(dptr, SessLinemode, SessPrefsPtr->linemode);
  853.     SetCntrl(dptr, SessTEKclear, SessPrefsPtr->tekclear);
  854.     SetCntrl(dptr, SessHalfDuplex, SessPrefsPtr->halfdup);
  855.     SetCntrl(dptr, SessLowLevelErrs, SessPrefsPtr->showlowlevelerrors);
  856.     SetCntrl(dptr, SessAuthenticate, SessPrefsPtr->authenticate);
  857.     SetCntrl(dptr, SessEncrypt, SessPrefsPtr->encrypt);
  858.     SetCntrl(dptr, SessLocalEcho, SessPrefsPtr->localecho);
  859.     SetTEText(dptr, SessHostName, SessPrefsPtr->hostname);
  860.     SetTEText(dptr, SessAlias, PrefRecordNamePtr);
  861.     NumToString(SessPrefsPtr->port, scratchPstring);
  862.     SetTEText(dptr, SessPort, scratchPstring);
  863.     NumToString(SessPrefsPtr->pasteblocksize, scratchPstring);
  864.     SetTEText(dptr, SessBlockSize, scratchPstring);
  865.     scratchPstring[0] = 2;
  866.     scratchPstring[1] = '^';
  867.     if (SessPrefsPtr->ckey != -1) {
  868.         scratchPstring[2] = SessPrefsPtr->ckey ^ 64;
  869.         SetTEText(dptr, SessInterrupt, scratchPstring);
  870.         }
  871.     if (SessPrefsPtr->skey != -1) {
  872.         scratchPstring[2] = SessPrefsPtr->skey ^ 64;
  873.         SetTEText(dptr, SessSuspend, scratchPstring);
  874.         }
  875.     if (SessPrefsPtr->qkey != -1) {
  876.         scratchPstring[2] = SessPrefsPtr->qkey ^ 64;
  877.         SetTEText(dptr, SessResume, scratchPstring);
  878.         }
  879.     for(scratchshort = CountMItems(SPopup[0].h); scratchshort; scratchshort--) {
  880.         GetItem(SPopup[0].h, scratchshort, scratchPstring);
  881.         if (EqualString(scratchPstring, (SessPrefsPtr->TerminalEmulation), TRUE, FALSE))
  882.             SPopup[0].choice = scratchshort;
  883.         }
  884.     for(scratchshort = CountMItems(SPopup[1].h); scratchshort; scratchshort--) {
  885.         GetItem(SPopup[1].h, scratchshort, scratchPstring);
  886.         if (EqualString(scratchPstring, (SessPrefsPtr->TranslationTable), TRUE, FALSE))
  887.             SPopup[1].choice = scratchshort;
  888.         }
  889.     
  890.     NumberOfColorBoxes = 0;
  891.     ZeroNumOnly();
  892.     NumOnly[0] = SessSafeItem;
  893.     NumOnly[1] = SessPort;  NumOnly[2] = SessBlockSize;
  894.     
  895.     SelIText(dptr, SessAlias, 0, 32767);
  896.     ShowWindow(dptr);
  897.     
  898.     while (ditem > 2) {
  899.         ModalDialog(SessionModalProcUPP, &ditem);
  900.         switch (ditem) {
  901.             case    SessForceSave:
  902.             case    SessBezerkeley:
  903.             case    SessLinemode:
  904.             case    SessTEKclear:
  905.             case    SessHalfDuplex:
  906.             case    SessLowLevelErrs:
  907.             case    SessAuthenticate:
  908.             case    SessEncrypt:
  909.             case    SessLocalEcho:
  910.                 FlipCheckBox(dptr, ditem);
  911.                 break;
  912.             
  913.             case    SessTEKinhib:
  914.                 SetCntrl(dptr, SessTEKinhib, 1);
  915.                 SetCntrl(dptr, SessTEK4014, 0);
  916.                 SetCntrl(dptr, SessTEK4105, 0);
  917.                 break;
  918.             case    SessTEK4014:
  919.                 SetCntrl(dptr, SessTEKinhib, 0);
  920.                 SetCntrl(dptr, SessTEK4014, 1);
  921.                 SetCntrl(dptr, SessTEK4105, 0);
  922.                 break;
  923.             case    SessTEK4105:
  924.                 SetCntrl(dptr, SessTEKinhib, 0);
  925.                 SetCntrl(dptr, SessTEK4014, 0);
  926.                 SetCntrl(dptr, SessTEK4105, 1);
  927.                 break;
  928.                 
  929.             case    SessPasteQuick:
  930.             case    SessPasteBlock:
  931.                 FlipRadioButton(dptr, SessPasteQuick);
  932.                 FlipRadioButton(dptr, SessPasteBlock);
  933.                 break;
  934.  
  935.             case    SessDeleteDel:
  936.             case    SessDeleteBS:
  937.                 FlipRadioButton(dptr, SessDeleteDel);
  938.                 FlipRadioButton(dptr, SessDeleteBS);
  939.                 break;
  940.  
  941.             case    SessInterrupt:
  942.             case    SessSuspend:
  943.             case    SessResume:
  944.                 GetTEText(dptr, ditem, scratchPstring);
  945.                 if ((scratchPstring[1] < 32) && (scratchPstring[1] > 0)) {
  946.                     scratchPstring[0] = 2;
  947.                     scratchPstring[2] = scratchPstring[1] ^ 64;
  948.                     scratchPstring[1] = '^';
  949.                     SetTEText(dptr, ditem, scratchPstring);
  950.                     }
  951.                 break;
  952.                 
  953.             default:
  954.                 break;
  955.             
  956.             } // switch
  957.         } // while
  958.         
  959.     GetItem(SPopup[0].h, SPopup[0].choice, scratchPstring);
  960.     GetItem(SPopup[1].h, SPopup[1].choice, scratchPstring2);
  961.     PopupCleanup();
  962.  
  963.     if (ditem == 2) {
  964.         if (IsNewPrefRecord) DisposeHandle((Handle) SessPrefsHdl);
  965.         else ReleaseResource((Handle) SessPrefsHdl);
  966.         
  967.         DisposeDialog(dptr);
  968.         return(FALSE);            // No changes should be made.
  969.         }
  970.         
  971.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  972.     BlockMove(scratchPstring, (SessPrefsPtr->TerminalEmulation), scratchPstring[0]+1);
  973.  
  974.     if (Length(scratchPstring2) > 63) scratchPstring[0] = 63;
  975.     BlockMove(scratchPstring2, (SessPrefsPtr->TranslationTable), scratchPstring2[0]+1);
  976.  
  977.     SessPrefsPtr->tektype = (-1 * GetCntlVal(dptr, SessTEKinhib)) + GetCntlVal(dptr, SessTEK4105);
  978.     SessPrefsPtr->pastemethod = !GetCntlVal(dptr, SessPasteQuick);
  979.     SessPrefsPtr->bksp = GetCntlVal(dptr, SessDeleteDel);
  980.     SessPrefsPtr->forcesave = GetCntlVal(dptr, SessForceSave);
  981.     SessPrefsPtr->crmap = GetCntlVal(dptr, SessBezerkeley);
  982.     SessPrefsPtr->linemode = GetCntlVal(dptr, SessLinemode);
  983.     SessPrefsPtr->tekclear = GetCntlVal(dptr, SessTEKclear);
  984.     SessPrefsPtr->halfdup = GetCntlVal(dptr, SessHalfDuplex);
  985.     SessPrefsPtr->showlowlevelerrors = GetCntlVal(dptr, SessLowLevelErrs);
  986.     SessPrefsPtr->authenticate = GetCntlVal(dptr, SessAuthenticate);
  987.     SessPrefsPtr->encrypt = GetCntlVal(dptr, SessEncrypt);
  988.     SessPrefsPtr->localecho = GetCntlVal(dptr, SessLocalEcho);
  989.  
  990.     GetTEText(dptr, SessPort, scratchPstring);
  991.     StringToNum(scratchPstring, &scratchlong);
  992.     BoundsCheck(&scratchlong, 65530, 1);
  993.     SessPrefsPtr->port = (short) scratchlong;
  994.  
  995.     GetTEText(dptr, SessBlockSize, scratchPstring);
  996.     StringToNum(scratchPstring, &scratchlong);
  997.     BoundsCheck(&scratchlong, 4097, 100);
  998.     SessPrefsPtr->pasteblocksize = (short) scratchlong;
  999.  
  1000.     GetTEText(dptr, SessHostName, scratchPstring);
  1001.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  1002.     BlockMove(scratchPstring, SessPrefsPtr->hostname, scratchPstring[0]+1);
  1003.     
  1004.     GetTEText(dptr, SessHostName, scratchPstring);
  1005.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  1006.     BlockMove(scratchPstring, SessPrefsPtr->hostname, scratchPstring[0]+1);
  1007.  
  1008.     GetTEText(dptr, SessAlias, PrefRecordNamePtr);
  1009.  
  1010.     GetTEText(dptr, SessInterrupt, scratchPstring);
  1011.     if (scratchPstring[0]) SessPrefsPtr->ckey = toupper(scratchPstring[2]) ^ 64;
  1012.     else SessPrefsPtr->ckey = -1;
  1013.     
  1014.     GetTEText(dptr, SessSuspend, scratchPstring);
  1015.     if (scratchPstring[0]) SessPrefsPtr->skey = toupper(scratchPstring[2]) ^ 64;
  1016.     else SessPrefsPtr->skey = -1;
  1017.     
  1018.     GetTEText(dptr, SessResume, scratchPstring);
  1019.     if (scratchPstring[0]) SessPrefsPtr->qkey = toupper(scratchPstring[2]) ^ 64;
  1020.     else SessPrefsPtr->qkey = -1;
  1021.     
  1022.     if (IsNewPrefRecord) {
  1023.         UseResFile(TelInfo->SettingsFile);
  1024.         resourceID = UniqueID(SESSIONPREFS_RESTYPE);
  1025.         AddResource((Handle)SessPrefsHdl, SESSIONPREFS_RESTYPE, resourceID, PrefRecordNamePtr);
  1026.         UpdateResFile(TelInfo->SettingsFile);
  1027.         ReleaseResource((Handle)SessPrefsHdl);
  1028.         }
  1029.     else {
  1030.         UseResFile(TelInfo->SettingsFile);
  1031.         GetResInfo((Handle)SessPrefsHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring);
  1032.         SetResInfo((Handle)SessPrefsHdl, resourceID, PrefRecordNamePtr);
  1033.         ChangedResource((Handle)SessPrefsHdl);
  1034.         UpdateResFile(TelInfo->SettingsFile);
  1035.         ReleaseResource((Handle)SessPrefsHdl);
  1036.         }
  1037.     
  1038.     DisposeDialog(dptr);
  1039.     return(TRUE);            // A resource has changed or been added.    
  1040. }
  1041.  
  1042. Boolean EditFTPUser(StringPtr PrefRecordNamePtr)
  1043. {
  1044.     DialogPtr    dptr;
  1045.     short        ditem, scratchshort, resourceID, vRefNum;
  1046.     ResType        scratchResType;
  1047.     Boolean        IsNewPrefRecord;
  1048.     FTPUser**    FTPUHdl;
  1049.     FTPUser*    FTPUptr;
  1050.     Str255        scratchPstring, scratchPstring2;
  1051.  
  1052.     dptr = GetNewMySmallStrangeDialog(FTPUserDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  1053.     ditem = 3;
  1054.  
  1055.     HideDItem(dptr, FTPUcanchangeCWD);        // Sometime later, perhaps
  1056.         
  1057.     if (PrefRecordNamePtr[0] != 0) {
  1058.         IsNewPrefRecord = FALSE;
  1059.         UseResFile(TelInfo->SettingsFile);
  1060.         FTPUHdl = (FTPUser **)Get1NamedResource(FTPUSER, PrefRecordNamePtr);
  1061.         HLock((Handle) FTPUHdl);
  1062.         FTPUptr = *FTPUHdl;
  1063.         SetCntrl(dptr, FTPUcanchangeCWD, FTPUptr->UserCanCWD);
  1064.         SetTEText(dptr, FTPUusername, PrefRecordNamePtr);
  1065.         for (scratchshort = 8, scratchPstring[0] = 8; scratchshort > 0; scratchshort--)
  1066.             scratchPstring[scratchshort] = '•';
  1067.          SetTEText(dptr, FTPUpassword, scratchPstring);
  1068.         vRefNum = VolumeNameToRefNum(FTPUptr->DefaultDirVolName);
  1069.         }
  1070.     else {
  1071.         IsNewPrefRecord = TRUE;
  1072.         FTPUHdl = (FTPUser **)NewHandleClear(sizeof(FTPUser));
  1073.         HLock((Handle) FTPUHdl);
  1074.         FTPUptr = *FTPUHdl;
  1075.         vRefNum = -1;                        // Default Volume
  1076.         FTPUptr->DefaultDirDirID = 2;        // Root directory
  1077.         SetCntrl(dptr, FTPUcanchangeCWD, 0);
  1078.         }
  1079.  
  1080.     PathNameFromDirID(FTPUptr->DefaultDirDirID, vRefNum, scratchPstring);
  1081.     SetTEText(dptr, FTPUDfltDirDsply, scratchPstring);
  1082.     
  1083.     SelIText(dptr, FTPUusername, 0, 32767);
  1084.     ShowWindow(dptr);
  1085.     
  1086.     while (ditem > 2) {
  1087.         ModalDialog(DLOGwOK_CancelUPP, &ditem);
  1088.         switch (ditem) {
  1089.             case    FTPUcanchangeCWD:
  1090.                 FlipCheckBox(dptr, ditem);
  1091.                 break;
  1092.             
  1093.             case    FTPUDfltDirButton:
  1094.                 SelectDirectory(&vRefNum, &(FTPUptr->DefaultDirDirID));
  1095.                 PathNameFromDirID(FTPUptr->DefaultDirDirID, vRefNum, scratchPstring);
  1096.                 SetTEText(dptr, FTPUDfltDirDsply, scratchPstring);
  1097.                 break;
  1098.                 
  1099.             default:
  1100.                 break;
  1101.             
  1102.             } // switch
  1103.         } // while
  1104.         
  1105.     if (ditem == 2) {
  1106.         if (IsNewPrefRecord) DisposeHandle((Handle) FTPUHdl);
  1107.         else ReleaseResource((Handle) FTPUHdl);
  1108.         
  1109.         DisposeDialog(dptr);
  1110.         return(FALSE);            // No changes should be made.
  1111.         }
  1112.         
  1113.     FTPUptr->UserCanCWD = GetCntlVal(dptr, FTPUcanchangeCWD);
  1114.     GetDirectoryName(vRefNum, 2, FTPUptr->DefaultDirVolName);
  1115.     
  1116.     GetTEText(dptr, FTPUusername, PrefRecordNamePtr);
  1117.     GetTEText(dptr, FTPUpassword, scratchPstring);
  1118.     
  1119.     if (scratchPstring[0] != '•') {
  1120.         // Encrypt the new (or possibly modified) password.
  1121.         PtoCstr(scratchPstring);
  1122.         Sencompass((char *)scratchPstring, (char *)scratchPstring2);
  1123.         CtoPstr((char *)scratchPstring2);
  1124.         BlockMove(scratchPstring2, FTPUptr->EncryptedPassword, Length(scratchPstring2)+1);
  1125.         }
  1126.             
  1127.     if (IsNewPrefRecord) {
  1128.         UseResFile(TelInfo->SettingsFile);
  1129.         resourceID = UniqueID(FTPUSER);
  1130.         AddResource((Handle)FTPUHdl, FTPUSER, resourceID, PrefRecordNamePtr);
  1131.         UpdateResFile(TelInfo->SettingsFile);
  1132.         ReleaseResource((Handle)FTPUHdl);
  1133.         }
  1134.     else {
  1135.         UseResFile(TelInfo->SettingsFile);
  1136.         GetResInfo((Handle)FTPUHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring);
  1137.         SetResInfo((Handle)FTPUHdl, resourceID, PrefRecordNamePtr);
  1138.         ChangedResource((Handle)FTPUHdl);
  1139.         UpdateResFile(TelInfo->SettingsFile);
  1140.         ReleaseResource((Handle)FTPUHdl);
  1141.         }
  1142.     
  1143.     DisposeDialog(dptr);
  1144.     return(TRUE);            // A resource has changed or been added.    
  1145. }
  1146.